package controleur;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import modele.Etat;
import modele.Evenement;
import reveil.Reveil;
import vue.VueConsole;

public class ControleurMatrice implements IControleur {

	private VueConsole vue;
	private final Reveil rev = Reveil.getInstance();
	private final HashMap<Etat, boolean[]> matrice = new HashMap<Etat, boolean[]>();
	private final List<Evenement> listEvenement = new ArrayList<>();

	public ControleurMatrice() {

		boolean[] non_arme = { true, false, false, false, false, false };
		matrice.put(Etat.NON_ARME, non_arme);

		boolean[] en_attente_declenchement = { false, true, false, false,
				false, true };
		matrice.put(Etat.EN_ATTENTE_DECLENCHEMENT, en_attente_declenchement);

		boolean[] en_sonnerie = { false, true, true, false, true, false };
		matrice.put(Etat.EN_SONNERIE, en_sonnerie);

		boolean[] en_repit = { false, true, false, true, false, false };
		matrice.put(Etat.EN_REPIT, en_repit);
	}

	@Override
	public void traiterEtat() {

		listEvenement.clear();
		Evenement[] evenements = { Evenement.ARMER_REVEIL,
				Evenement.DESARMER_REVEIL, Evenement.APRES_1MN,
				Evenement.APRES_15MN, Evenement.METTRE_EN_REPIT,
				Evenement.WHEN_HC_HS };

		boolean[] evenementPossible = matrice.get(rev.getEtat());

		for (int i = 0; i < evenementPossible.length; i++) {
			if (evenementPossible[i]) {
				listEvenement.add(evenements[i]);
			}
		}

		vue.afficherVue(listEvenement);

	}

	@Override
	public void traiterEvenement(Evenement evenement) {

		boolean effectuerAction = matrice.get(rev.getEtat())[evenement
				.getNumEvenement() - 1];

		if (effectuerAction) {
			Class<?> clazz = rev.getClass();
			Method m = null;

			try {
				m = clazz.getDeclaredMethod(evenement.getNomMethode(),
						(Class[]) null);

				if (null != m) {
					m.invoke(rev, (Object[]) null);
				}
			} catch (NoSuchMethodException | SecurityException
					| IllegalAccessException | IllegalArgumentException
					| InvocationTargetException e) {
				e.printStackTrace();
			}

		}

		this.traiterEtat();
	}

	public VueConsole getVue() {
		return vue;
	}

	public void setVue(VueConsole vue) {
		this.vue = vue;
	}

	public Reveil getRev() {
		return rev;
	}
}
